# -*- coding:utf-8 -*-

from redis_om import FindQuery
from sqlalchemy.sql import and_, or_, ColumnElement
from sqlalchemy import Column
from typing import Any

from .models import StorageMode


class HybridQuery(FindQuery):
    def __init__(self, model_cls, session):
        self.model_cls = model_cls
        self.session = session
        self._conditions = []

    def filter(self, *conditions: Any) -> "HybridQuery":
        """统一查询条件"""
        self._conditions.extend(conditions)
        return self

    def _execute_redis_query(self):
        """执行 Redis-OM 查询"""
        # 调用 Redis-OM 的正确方法（原 find() 需构造查询表达式）
        return self.model_cls.find(
            *self._conditions,
            session=self.session.engine.redis
        ).all()

    def _execute_sql_query(self) -> list:
        """执行 SQL 查询"""
        sql_conditions = [self._convert_condition(c) for c in self._conditions]
        return self.session.sql_session.query(self.model_cls).filter(and_(*sql_conditions)).all()

    def _convert_condition(self, condition: Any) -> ColumnElement:
        """将 Redis-OM 条件转换为 SQLAlchemy 条件"""
        # 解析 Redis-OM 的条件对象结构（示例）
        if hasattr(condition, "left") and hasattr(condition, "op"):
            column: Column = getattr(self.model_cls, condition.left.key)
            value = condition.right

            # 操作符映射
            op_mapping = {
                "eq": "__eq__",
                "gt": "__gt__",
                "lt": "__lt__",
                "ge": "__ge__",
                "le": "__le__",
                "ne": "__ne__",
                "in": "in_",
                "not_in": "notin_",
                "%": "like"
            }

            if condition.op in op_mapping:
                sql_op = getattr(column, op_mapping[condition.op])
                return sql_op(value)
            else:
                raise ValueError(f"不支持的查询操作符: {condition.op}")

        raise TypeError(f"无法转换的条件类型: {type(condition)}")

    def all(self, **kwargs) -> list:  # 添加 **kwargs 保持签名兼容
        """执行查询并返回结果"""
        if self.model_cls.__storage_mode__ == StorageMode.REDIS:
            return self._execute_redis_query()
        else:
            return self._execute_sql_query()